﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace GoodStuff.Text
{
    public static class TextExtensions
    {
        const double dKB = 1024;
        const double dMB = dKB*1024;

        public static string ToSizeFormat(this int size)
        {   
            return ToSizeFormat((long)size);
        }

        public static string ToSizeFormat(this long size)
        {
            double dsize = (double)size;    //gives me fractions.

            if (dsize < dKB)
                return string.Format("{0} bytes", dsize);

            if (dsize >= dKB && dsize < dMB)
                return string.Format("{0:0.0} Kb", dsize / dKB);
            
            return string.Format("{0:0.0} Mb", dsize / dMB);
        }

        /// <summary>
        /// This will convert a timespan into an indication of the age.
        /// It is usually not interesting exactly to know the exact second something happened,
        /// just that it happend '3 days ago'.
        /// </summary>
        /// <param name="age"></param>
        /// <returns></returns>
        public static string ToAge(this DateTime age)
        {
            TimeSpan diff = DateTime.Now - age;
            return diff.ToAge();
                     
        }

        /// <summary>
        /// This will convert a timespan into an indication of the age.
        /// It is usually not interesting exactly to know the exact second something happened,
        /// just that it happend '3 days ago'.
        /// </summary>
        /// <param name="diff"></param>
        /// <returns></returns>
        public static string ToAge(this TimeSpan diff)
        {
            if (diff.TotalSeconds < 45)
            {
                return Math.Round(diff.TotalSeconds).ToString() + " seconds";
            }
            if (diff.TotalMinutes < 1)
            {
                return "Less than a minute";
            }
            if (diff.TotalMinutes < 2)
            {
                return "About a minute";
            }
            if (diff.TotalMinutes < 30)
            {
                return Math.Round(diff.TotalMinutes).ToString() + " minutes";
            }
            if (diff.TotalMinutes < 45)
            {
                return "Half an hour";
            }
            if (diff.TotalHours < 1)
            {
                return "Almost an hour";
            }
            if (diff.TotalHours < 24)
            {
                return Math.Round(diff.TotalHours).ToString() + " hours";
            }
            if (diff.Days < 7)
            {
                return diff.Days.ToString() + " days";
            }

            if (diff.Days < 14)
            {
                return "1 week";
            }

            if (diff.Days < 60)
            {
                return (diff.Days / 7).ToString() + " weeks";
            }
            return "Many days";  
        }

        /// <summary>
        /// Ensures the given string ends with the given argument
        /// </summary>
        /// <param name="text"></param>
        /// <param name="endsWith"></param>
        /// <returns></returns>
        public static string EnsureEndWith(this string text, string endsWith)
        {
            if (text == null)
                return endsWith;

            if (text.EndsWith(endsWith))
            {
                return text;
            }
            else
            {
                return text + endsWith;
            }
        }

        /// <summary>
        /// Ensures the given string ends with a forward slash (commonly used within filepaths)
        /// </summary>
        /// <param name="text"></param>
        /// <returns></returns>
        public static string EnsureEndWithSlash(this string text)
        {
            return EnsureEndWith(text, "/");
        }

        /// <summary>
        /// Makes sure that a string is never more than 'maxLength' characters, by appending '...' at the end.
        /// </summary>
        /// <param name="text"></param>
        /// <param name="maxLength"></param>
        /// <returns></returns>
        public static string Limit(this string text, int maxLength)
        {
            if (maxLength < 5)
            {
                throw new ArgumentOutOfRangeException("maxLength", "should be greater or equal to 5");
            }
            if (text != null)
            {
                if (text.Length > maxLength)
                {
                    text = text.Substring(0, maxLength - 3) + "...";
                }
            }

            return text;
        }
    }
}
